import asyncio
import aiohttp
import uuid
import math
from config import LiveConfig


class RealLive(LiveConfig):
    def __init__(self):
        self.loop = asyncio.get_event_loop()
        self.max_page = 137

    async def start_request(self, url, methods='GET', _data=None):
        try:
            connector = aiohttp.TCPConnector(verify_ssl=False)
            async with aiohttp.ClientSession(connector=connector) as session:
                action = session.get if methods == 'GET' else session.post
                async with action(url) as resp:
                    if resp.status == 200:
                        c_type = resp.headers.get('CONTENT-TYPE', '').lower()
                        if 'json' in c_type or url.endswith('json'):
                            data = await resp.json()
                        else:
                            data = await resp.read()
                        return data
                    else:
                        return None
        except Exception as e:
            print(e)
            print(44)
            return None

    def save_single_file(self, byte_data):
        pass

    async def get_max_count(self):
        data = await self.start_request(self.ACTION['GET_LIST'].format(1))
        if data and data['status']:
            self.max_page = data['data']['total']
        else:
            raise Exception

    def get_list(self):
        mp = math.ceil(self.max_page / 15)
        page_tasks = [asyncio.ensure_future(self.get_page_data(_)) for _ in range(1, mp + 1)]
        self.loop.run_until_complete(asyncio.wait(page_tasks))
        print([_.result() for _ in page_tasks])

    async def get_page_data(self, page):
        print('get_page_data_start', page)
        data = await self.start_request(self.ACTION['GET_LIST'].format(page))
        print('get_page_data_end', page)
        if data and data['status']:
            ids = [_['info']['id'] for _ in data['data']['items']]
        else:
            ids = []
        get_pre_page_tasks = [asyncio.ensure_future(self.get_per_data(_)) for _ in ids]
        dones, pendings = await asyncio.wait(get_pre_page_tasks)
        return [_.result() for _ in dones]

    async def get_per_data(self, _id):
        # print('get_per_data_start', _id)
        # print(self.ACTION['GET_SINGLE'].format(_id))
        data = await self.start_request(self.ACTION['GET_SINGLE'].format(_id))
        if data and data['status']:
            images = [_['img'] for _ in data['data']['images']]
        else:
            images = []
        if len(images) == 0:
            return []
        get_image_byte_tasks = [asyncio.ensure_future(self.start_request(_)) for _ in images]
        dones, pendings = await asyncio.wait(get_image_byte_tasks)
        images_byte_datas = [_.result() for _ in dones]
        save_image_tasks = [asyncio.ensure_future(self.save_image(_)) for _ in images_byte_datas]
        dones, pendings = await asyncio.wait(save_image_tasks)
        local_image_paths = [_.result() for _ in dones]
        return local_image_paths

    async def save_image(self, byte_data):
        path = await self.loop.run_in_executor(None, self.save_image_fn, byte_data)
        return path

    def save_image_fn(self, byte_data):
        filename = str(uuid.uuid1()) + '.jpg'
        try:
            with open(self.SAVE_IMAGE_PATH + filename, 'wb') as f:
                f.write(byte_data)
                return filename
        except Exception as e:
            return None

    def run(self):
        get_max_page_cor = asyncio.ensure_future(self.get_max_count())
        try:
            self.loop.run_until_complete(get_max_page_cor)
        except Exception:
            print('get_max_page_error')
        self.get_list()
        '''
        cor = asyncio.ensure_future(self.get_per_data(400))
        self.loop.run_until_complete(cor)
        print(cor.result())
        '''

    def close(self):
        self.loop.close()


if __name__ == '__main__':
    live = live = RealLive()
    live.run()
